package com.pxmeta.party.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pxmeta.common.utils.StringUtils;
import com.pxmeta.party.entity.Gift;
import com.pxmeta.party.entity.LotteryLuckyUser;
import com.pxmeta.party.entity.vo.LuckyUserRankingVO;
import com.pxmeta.party.mapper.LotteryLuckyUserMapper;
import com.pxmeta.party.service.IActivityAdAstraUserRecordService;
import com.pxmeta.party.service.IGiftService;
import com.pxmeta.party.service.ILotteryLuckyUserService;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class LotteryLuckyUserServiceImpl extends ServiceImpl<LotteryLuckyUserMapper, LotteryLuckyUser> implements ILotteryLuckyUserService {

    @Autowired
    private IActivityAdAstraUserRecordService activityAdAstraUserRecordService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IGiftService giftService;


    @Override
    public List<Map<String, Object>> getLotteryRecord(Long userId) {
        LambdaQueryWrapper<LotteryLuckyUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LotteryLuckyUser::getUserId, userId)
                .orderByDesc(LotteryLuckyUser::getCreateTime);

        List<LotteryLuckyUser> list = this.list(wrapper);

        if (list.isEmpty()){
            return Lists.newArrayList();
        }
        List<Integer> giftIds = list.stream().map(LotteryLuckyUser::getGiftId).collect(Collectors.toList());


        List<Gift> gifts = giftService.listByIds(giftIds);
        Map<Long, List<LotteryLuckyUser>> collect = list.stream().collect(Collectors.groupingBy(LotteryLuckyUser::getRecordId));
        Set<Map.Entry<Long, List<LotteryLuckyUser>>> entries = collect.entrySet();
        List<Map<String, Object>> finalList = Lists.newLinkedList();
        for (Map.Entry<Long, List<LotteryLuckyUser>> entry : entries) {
            Map<String, Object> map = Maps.newHashMap();
            List<LotteryLuckyUser> values = entry.getValue();
            Integer totalCount =0;
            LocalDateTime time = LocalDateTime.now();
            for (LotteryLuckyUser value : values) {
                Integer count = value.getCount();
                Integer giftId = value.getGiftId();

                Optional<Gift> first = gifts.stream().filter(g -> g.getId().equals(giftId)).findFirst();
                if (first.isPresent()){
                    Gift gift = first.get();
                    value.setGiftIcon(gift.getIcon());
                    value.setGiftName(gift.getName());
                }
                totalCount += count;

                time=value.getCreateTime();
            }
            map.put("count", totalCount);
            map.put("time",time);
            map.put("list",values);
            finalList.add(map);
        }

        //todo 将finalList 根据time 时间倒序排序再返回。
        finalList.sort(Comparator.comparing(map -> (LocalDateTime) map.get("time"), Comparator.reverseOrder()));
        return finalList;
    }

    @Override
    public List<LuckyUserRankingVO> getLotteryRanking(Integer type, Integer page, Integer size) {
        List<LuckyUserRankingVO> list = baseMapper.getLotteryRanking(new Page<>(page, size), type);
        if (!list.isEmpty()){
            List<Long> userIds = list.stream().map(LuckyUserRankingVO::getUserId).collect(Collectors.toList());
            List<User> users = userService.listByIds(userIds);
            for (LuckyUserRankingVO vo : list) {
                Optional<User> first = users.stream().filter(u -> u.getId().equals(vo.getUserId())).findFirst();
                if (first.isPresent()){
                    User user = first.get();
                    vo.setUser(user);
                }
            }
        }
        return list;
    }

    @Override
    public LuckyUserRankingVO getCurrentUserRanking(Long userId, Integer type) {
        LambdaQueryWrapper<LotteryLuckyUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LotteryLuckyUser::getUserId, userId);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime of = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 0, 0);
        if (type == 1){
            wrapper.ge(LotteryLuckyUser::getCreateTime,of);
        }
        List<LotteryLuckyUser> list = this.list(wrapper);
        Integer totalPrice = 0;
        for (LotteryLuckyUser lotteryLuckyUser : list) {
            Integer price = lotteryLuckyUser.getPrice();
            totalPrice += price;
        }
        List<LuckyUserRankingVO> vos = getLotteryRanking(type, 1, 100);
        User user = userService.getById(userId);
        LuckyUserRankingVO vo = new LuckyUserRankingVO();
        vo.setTotalPrice(totalPrice);
        vo.setUserId(userId);
        vo.setUser(user);
        for (int i = 0; i < vos.size(); i++) {
            LuckyUserRankingVO vo1 = vos.get(i);
            if(vo1.getUserId().equals(userId)){
                vo.setRanking(i+1);
                break;
            }
        }
        return vo;
    }

    @Override
    public IPage<LotteryLuckyUser> getLotteryList(Integer page, Integer size, Integer type, String keyword) {

        if (type == 7){
            return activityAdAstraUserRecordService.getUserLotteryRecordPage(page, size,keyword);
        }

        return baseMapper.getUserLotteryRecordPage(new Page<>(page,size),type,keyword);
    }

    @Override
    public List<Gift> getLotteryItemList(Long recordId) {

        LambdaQueryWrapper<LotteryLuckyUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LotteryLuckyUser::getRecordId,recordId);

        List<LotteryLuckyUser> list = this.list(wrapper);
        List<Integer> giftIds = list.stream().map(LotteryLuckyUser::getGiftId).collect(Collectors.toList());
        if (!giftIds.isEmpty()){
            List<Gift> gifts = giftService.listByIds(giftIds);
            for (Gift gift : gifts) {
                Optional<LotteryLuckyUser> first = list.stream().filter(l -> l.getGiftId().equals(gift.getId())).findFirst();
                if (first.isPresent()){
                    Integer count = first.get().getCount();
                    gift.setCount(count);
                }
            }
            return gifts;
        }

        return Lists.newArrayList();

    }

    @Override
    public List<LotteryLuckyUser> getByRecordId(Long userId, Long recordId) {
        LambdaQueryWrapper<LotteryLuckyUser> wrapper = Wrappers.lambdaQuery();
        if (recordId != null){
           wrapper.eq(LotteryLuckyUser::getRecordId, recordId);
        }

        wrapper.eq(LotteryLuckyUser::getUserId, userId)
                .eq(LotteryLuckyUser::getType, 7)
                .ne(LotteryLuckyUser::getPrice, 0);


        return this.list(wrapper);
    }

    @Override
    public List<LotteryLuckyUser> getByRecordId(Long recordId) {
        LambdaQueryWrapper<LotteryLuckyUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(LotteryLuckyUser::getRecordId, recordId)
                .eq(LotteryLuckyUser::getType,7);
        return this.list(wrapper);
    }
}
